home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / aminet / os20 / cdity / qmouse270.lha / qmouse.s < prev   
Text File  |  1993-04-18  |  39KB  |  2,008 lines

  1. ;QMouse.s
  2. ;Written by Dan Babcock
  3.  
  4. ;This source was assembled with Macro68 release 3.
  5.  
  6. Macro68    equ    1
  7. DevPac3    equ    2
  8.  
  9. ASM    equ    Macro68
  10.  
  11.     IFEQ    ASM-Macro68
  12.     exeobj
  13.     objfile    'c:QMouse'
  14.     MC68000
  15.     multipass
  16.     ENDC
  17.     IFEQ    ASM-DevPac3
  18.     include    'exec/types.i'
  19.     include    'exec/exec.i'
  20.     include    'dos/dos_lib.i'
  21.     include    'dos/dos.i'
  22.     include    'dos/dostags.i'
  23.     include    'dos/dosextens.i'
  24.     include    'intuition/intuition.i'
  25.     include    'intuition/intuitionbase.i'
  26.     include    'intuition/intuition_lib.i'
  27.     include    'graphics/graphics_lib.i'
  28.     include    'graphics/layers_lib.i'
  29.     include    'graphics/copper.i'
  30.     include    'graphics/gfxbase.i'
  31.     include    'hardware/custom.i'
  32.     include    'hardware/dmabits.i'
  33.     include    'hardware/intbits.i'
  34.     include    'exec/exec_lib.i'
  35.     include    'devices/timer.i'
  36.     include    'devices/input.i'
  37.     include    'devices/inputevent.i'
  38.     include    'devices/trackdisk.i'
  39.     ENDC
  40.  
  41. ;Some V39 equates
  42.  
  43.     IFND    _LVOSetWindowPointerA
  44. _LVOSetWindowPointerA    equ    -$330
  45.     ENDC
  46.     IFND    WA_BusyPointer
  47. WA_BusyPointer    equ    $80000098
  48.     ENDC
  49.     IFND    WA_Pointer
  50. WA_Pointer    equ    $80000097
  51.     ENDC
  52.  
  53. ;End V39 equates
  54.  
  55.  
  56.     IFND    SYS
  57. SYS    macro
  58.     jsr    _LVO\1(a6)
  59.     endm
  60.     ENDC
  61.  
  62.     IFND    _custom
  63. _custom    equ    $dff000
  64.     ENDC
  65.  
  66.     IFND    _LVOSystemTagList
  67. _LVOSystemTagList    equ    -$25E
  68.     ENDC
  69.  
  70.     IFND    push
  71. push    macro
  72.     move.l    \1,-(sp)
  73.     endm
  74.     ENDC
  75.     IFND    pop
  76. pop    macro
  77.     move.l    (sp)+,\1
  78.     endm
  79.     ENDC
  80.  
  81. ;Set INFO_LEVEL to 1 for full debugging output.
  82. INFO_LEVEL    equ    0
  83.  
  84. ;Put a message to the serial port.  Used like so:
  85. ;
  86. ;PUTDEBUG    <'Init: called'>
  87. ;
  88. ;Parameters can be printed out by pushing them on the stack and
  89. ;adding the appropriate C printf-style % formatting commands.
  90.  
  91. PUTDEBUG     macro    ;<msg>
  92.     ifne    INFO_LEVEL
  93.     movem.l    d0-d1/a0-a1,-(sp)
  94.     lea    .msg\@(pc),a0    ;Point to static format string
  95.     lea    16(sp),a1    ;Point to args
  96.     bsr    KPutFmt
  97.     movem.l    (sp)+,d0-d1/a0-a1
  98.     bra    .end\@
  99. .msg\@:
  100.     dc.b    \1,$a,0
  101.     even
  102. .end\@:
  103.     endc
  104.     endm
  105.  
  106.  
  107. MAXQUEUE    equ    32
  108. SCREENLISTSIZE    equ    32    ;maximum number of screens to keep track of
  109. POINTERLISTSIZE    equ    32
  110. HANDLERPRI    equ    60    ;priority of input.device handler
  111. TaskPriority    equ    21
  112. ShellPriority    equ    0
  113. MaxCopperSize    equ    500
  114.  
  115. SysBackground    equ    $e    ;offset into gb_copinit copper list
  116. WindowStart    equ    $0    ;offset into LOF copper list
  117. DefColor    equ    $fff    ;white
  118. WaitLine    equ    $16
  119.  
  120.     move.l    4,a6
  121.     cmp.w    #37,LIB_VERSION(a6)
  122.     bhs    GoodVersion
  123.  
  124. ;Print an error message - the user doesn't have 2.0
  125.     lea    DosName(pc),a1
  126.     SYS    OldOpenLibrary
  127.     tst.l    d0
  128.     beq    ErrEnd
  129.     move.l    d0,a6
  130.     SYS    Output
  131.     move.l    d0,d1
  132.     moveq    #EndSorry-Sorry,d3
  133.     lea    Sorry(pc),a0
  134.     move.l    a0,d2
  135.     SYS    Write
  136.     move.l    a6,a1
  137.     move.l    4,a6
  138.     SYS    CloseLibrary
  139. ErrEnd:    moveq    #RETURN_FAIL,d0
  140.     rts
  141.  
  142.     dc.b    '$VER: QMouse 2.70 (19.4.93)',$a,0
  143. Sorry:    dc.b    'Sorry, this program requires Kickstart 2.0!',$a,0
  144. EndSorry:
  145. BadArgs:    dc.b    'Bad arguments.',$a,0
  146.     even
  147.  
  148. GoodVersion:
  149.  
  150. ;Allocate global data structure
  151.     move.l    #Data_Sizeof,d0
  152.     move.l    #MEMF_CLEAR,d1
  153.     SYS    AllocMem
  154.     tst.l    d0
  155.     beq    ErrEnd
  156.     move.l    d0,a5
  157.     lea    GlobalPtr(pc),a0
  158.     move.l    a5,(a0)
  159.  
  160. ;Allocate chip RAM data.
  161.     move.l    #CData_Sizeof,d0
  162.     move.l    #MEMF_CLEAR+MEMF_CHIP,d1
  163.     SYS    AllocMem
  164.     move.l    d0,ChipData(a5)
  165.     beq    CleanUp
  166.  
  167. ;Initialize static data
  168.     move.b    #HANDLERPRI,InputInterrupt+LN_PRI(a5)
  169.     move.l    a5,InputInterrupt+IS_DATA(a5)
  170.     moveq    #1,d0
  171.     move.l    d0,ClickCount(a5)    ;***BUG: WAS A1 (trashing memory)
  172.                 ;THANKS to Chris Schneider for finding
  173.                 ;it!!!!!!!!!!!!!!!!
  174.  
  175. ;Open libraries
  176.     lea    LibTable(pc),a2
  177.     move.l    a2,a3
  178.     moveq    #NumLibs-1,d2
  179. .OLibLoop:
  180.     move.w    (a2)+,a1
  181.     add.l    a3,a1
  182.     SYS    OldOpenLibrary
  183.     move.w    (a2)+,a0
  184.     add.l    a5,a0
  185.     move.l    d0,(a0)
  186.     beq    CleanUp
  187.     dbra    d2,.OLibLoop
  188.  
  189. ;Parse command line
  190.     lea    Template(pc),a0
  191.     move.l    a0,d1
  192.     lea    Options(a5),a0
  193.     move.l    a0,d2
  194.     moveq    #0,d3    ;no custom rdarg structure
  195.     move.l    DosBase(a5),a6
  196.     SYS    ReadArgs
  197.     move.l    d0,ArgPtr(a5)
  198.     bne    .ArgsOK
  199.     lea    BadArgs(pc),a0
  200.     move.l    a0,d1
  201.     SYS    VPrintf
  202.     bra    CleanUp
  203.  
  204. .ArgsOK:
  205.     move.l    4,a6
  206.  
  207. ;Process QUIT option, if selected.
  208.     tst.l    QuitOption(a5)
  209.     beq    .SkipQuit
  210.     lea    ProcName(pc),a1
  211.     SYS    FindTask
  212.     tst.l    d0
  213.     beq    CleanUp
  214.     move.l    d0,a1
  215.     move.l    TC_Userdata(a1),a0
  216.     move.l    QuitSig(a0),d0
  217.     SYS    Signal    ;tell task to quit
  218.     bsr    CleanUp
  219.     bra    .Exit
  220. .SkipQuit:
  221.  
  222. ;If already installed, kill the existing process.
  223.     lea    ProcName(pc),a1
  224.     SYS    FindTask
  225.     tst.l    d0
  226.     beq    .NotInstalled
  227.     move.l    d0,a1
  228.     move.l    TC_Userdata(a1),a0
  229.     move.l    QuitSig(a0),d0
  230.     SYS    Signal    ;tell task to quit
  231.  
  232.     moveq    #26,d2
  233. .Kill:    subq.l    #1,d2
  234.     beq    .Exit
  235.     move.l    DosBase(a5),a6
  236.     moveq    #2,d1
  237.     SYS    Delay
  238.     lea    ProcName(pc),a1
  239.     move.l    4,a6
  240.     SYS    FindTask
  241.     tst.l    d0
  242.     bne    .Kill
  243. .NotInstalled:
  244.  
  245. ;Get stack for command.
  246.     move.l    DosBase(a5),a6
  247.     SYS    Cli
  248.     move.l    d0,a0
  249.     move.l    cli_DefaultStack(a0),d0
  250.     lsl.l    #2,d0
  251.     lea    CmdStackSize(pc),a0
  252.     move.l    d0,(a0)
  253.     move.l    4,a6
  254.  
  255. ;Copy resident part of code into allocated memory
  256.     lea    StartAllocCode(pc),a0    ;source
  257.     lea    ResidentCode(a5),a1    ;destination
  258.     move.l    #ResidentCodeSize,d0    ;size
  259.     SYS    CopyMem
  260.     SYS    CacheClearU    ;for 020/030/040
  261.  
  262. ;Start a process
  263.     move.l    DosBase(a5),a6
  264.     lea    ResidentCode(a5),a0
  265.     lea    EntryPoint(pc),a1
  266.     move.l    a0,(a1)
  267.     lea    ProcName-StartAllocCode+ResidentCode(a5),a0
  268.     lea    ProcNamePtr(pc),a1
  269.     move.l    a0,(a1)
  270.     lea    NewProcTags(pc),a0
  271.     move.l    a0,d1
  272.     SYS    CreateNewProc
  273.  
  274. ;Exit back to CLI
  275. .Exit:    moveq    #0,d0
  276.     rts
  277.  
  278. ***************************************************************************
  279. * The following code is copied into allocated memory.                     *
  280. ***************************************************************************
  281.  
  282. StartAllocCode:
  283.     move.l    4,a6
  284.     move.l    GlobalPtr(pc),a5
  285.     lea    IntRoutine(pc),a0
  286.     move.l    a0,InputInterrupt+IS_CODE(a5)
  287.  
  288. ;Perform relocations.
  289.     lea    PatchAlert(pc),a1
  290.     movem.l    8(a1),d0-d2
  291.     add.l    a1,d0
  292.     add.l    a1,d1
  293.     add.l    a1,d2
  294.     movem.l    d0-d2,8(a1)
  295.  
  296. ;Initialize damping constant.
  297.     move.l    AccelOption(a5),d0
  298.     beq    .NoDamp
  299.     move.l    d0,a0
  300.     move.l    (a0),d0
  301.     subq.l    #1,d0
  302.     move.l    ThreshOption(a5),d1
  303.     beq    .DefThresh
  304.     move.l    d1,a0
  305.     move.l    (a0),d1
  306. .DefThresh:
  307.     addq.l    #1,d1
  308.     muls.w    d0,d1
  309.     move.w    d1,DampingConstant(a5)
  310. .NoDamp:
  311.  
  312. ;Allocate signals
  313.     moveq    #NumSigs-1,d2
  314.     lea    Sigs(a5),a2
  315. .SigLoop:    moveq    #-1,d0
  316.     SYS    AllocSignal
  317.     tst.l    d0
  318.     bmi    CleanUp
  319.     moveq    #0,d1
  320.     bset    d0,d1
  321.     move.l    d1,(a2)+
  322.     dbra    d2,.SigLoop
  323.  
  324. ;Initialize semaphore(s)
  325.     lea    Semaphores(a5),a2
  326.     moveq    #NumSemaphores-1,d2
  327. .InitSema:
  328.     move.l    a2,a0
  329.     SYS    InitSemaphore
  330.     lea    SS_SIZE(a2),a2
  331.     dbra    d2,.InitSema
  332.  
  333.     move.l    ThisTask(a6),a0
  334.     move.l    a0,Task(a5)
  335.     move.l    a5,TC_Userdata(a0)
  336.  
  337. ;Install no-flicker option if selected.
  338.     tst.l    FlickerOption(a5)
  339.     beq    .NoFlicker
  340.     move.l    GraphBase(a5),a0
  341.     move.l    gb_copinit(a0),a0
  342.     move.l    a0,OriginalCopInit(a5)
  343.     move.l    ChipData(a5),a1
  344.     lea    Copper(a1),a1
  345.     move.l    a1,a2
  346.     move.w    #MaxCopperSize/4-1,d0
  347. .CLoop:    move.l    (a0)+,d1
  348.     cmp.l    #$008A0000,d1
  349.     beq    .CopEnd
  350.     move.l    d1,(a1)+
  351.     dbra    d0,.CLoop
  352.     clr.l    FlickerOption(a5)
  353.     bra    .NoFlicker
  354. .CopEnd:    move.l    #$01800000,(a1)+
  355.     move.l    a1,WaitLineAddress(a5)
  356.     move.l    #$1607FFFE,(a1)+
  357.     move.w    #$0180,(a1)+
  358.     move.l    #$008A0000,2(a1)
  359.     move.l    a1,RealBackground(a5)
  360.     move.l    a2,cop1lc+_custom
  361.     move.l    GraphBase(a5),a0
  362.     move.l    a2,gb_copinit(a0)
  363.     cmp.w    #color,SysBackground-2(a2)
  364.     bne    .DefColor
  365.     move.w    SysBackground(a2),(a1)
  366.     bra    .NoFlicker
  367. .DefColor:
  368.     move.w    #DefColor,(a1)
  369. .NoFlicker:
  370.  
  371. ;Patch MANY system routines.
  372.     lea    PatchTable(pc),a2
  373.     move.l    a2,a3
  374. .Patch:    move.w    (a2)+,d0    ;get base
  375.     beq    .EndPatch
  376.     move.l    (a5,d0.w),a1    ;library base to patch
  377.     move.w    (a2)+,d0    ;get minimum library version
  378.     cmp.w    LIB_VERSION(a1),d0
  379.     bls    .VersionOK
  380.     addq.l    #6,a2
  381.     bra    .Patch
  382. .VersionOK:
  383.     move.w    (a2)+,d0    ;get offset to new routine
  384.     lea    (a3,d0.w),a0
  385.     move.l    a0,d0    ;new routine address
  386.     move.w    (a2)+,a0    ;_LVO offset
  387.     SYS    SetFunction
  388.     move.w    (a2)+,d1
  389.     move.l    d0,(a5,d1.w)
  390.     bra    .Patch
  391. .EndPatch:
  392.  
  393. ;Create an IORequest structure
  394.     SYS    CreateMsgPort
  395.     move.l    d0,InputMsgPort(a5)
  396.     beq    CleanUp
  397.     move.l    d0,a0
  398.     moveq    #IOSTD_SIZE,d0
  399.     SYS    CreateIORequest
  400.     move.l    d0,InputIORequest(a5)
  401.     beq    CleanUp
  402.  
  403. ;Perform NoClick, if desired.
  404.     move.l    NoClickOption(a5),d2
  405.     beq    .Click
  406.     move.l    d2,a0
  407.     move.l    (a0),d2
  408. .Click:    moveq    #0,d3
  409.     moveq    #3,d4
  410. .ClickLoop:
  411.     lea    TrackName(pc),a0    ;device name
  412.     move.l    d3,d0    ;unit number
  413.     move.l    InputIORequest(a5),a1    ;IO request
  414.     moveq    #0,d1    ;flags
  415.     SYS    OpenDevice
  416.     tst.l    d0
  417.     bne    .ECLoop
  418.     move.l    InputIORequest(a5),a1    ;IO request
  419.     move.l    IO_UNIT(a1),a0
  420.     btst    d3,d2
  421.     beq    .SkipNoClick
  422.     bset    #TDPB_NOCLICK,TDU_PUBFLAGS(a0)
  423. .SkipNoClick:
  424.     tst.l    VerifyOption(a5)
  425.     beq    .NoVerify
  426.     bset    #1,TDU_PUBFLAGS(a0)
  427. .NoVerify:
  428.     tst.l    NoVerifyOption(a5)
  429.     beq    .SkipVerify
  430.     bclr    #1,TDU_PUBFLAGS(a0)
  431. .SkipVerify:
  432.     SYS    CloseDevice
  433. .ECLoop:    addq.l    #1,d3
  434.     dbra    d4,.ClickLoop
  435.  
  436. ;Handle 'STAR' option.
  437.     tst.l    StarOption(a5)
  438.     beq    .NoStar
  439.     move.l    DosBase(a5),a0
  440.     move.l    dl_Root(a0),a0
  441.     bset    #0,rn_Flags(a0)
  442. .NoStar:
  443.  
  444. ;Open the input.device
  445.     lea    InputName(pc),a0    ;device name
  446.     moveq    #0,d0    ;unit number
  447.     move.l    InputIORequest(a5),a1    ;IO request
  448.     moveq    #0,d1    ;flags
  449.     SYS    OpenDevice
  450.     tst.l    d0
  451.     bne    CleanUp
  452.  
  453. ;Install virtical blank routine if needed.
  454.     tst.l    SunMouseOption(a5)
  455.     beq    .SkipVBL
  456.     moveq    #INTB_VERTB,d0
  457.     lea    VBlankServer(a5),a1
  458.     move.l    a5,IS_DATA(a1)
  459.     lea    VBlankRoutine(pc),a0
  460.     move.l    a0,IS_CODE(a1)
  461.     move.b    #NT_INTERRUPT,LN_TYPE(a1)
  462.     SYS    AddIntServer
  463.     bset    #STB_IntInstalled,Status(a5)
  464. .SkipVBL:
  465.  
  466. ;Install input handler
  467.     move.l    InputIORequest(a5),a1
  468.     move.w    #IND_ADDHANDLER,IO_COMMAND(a1)
  469.     lea    InputInterrupt(a5),a0
  470.     move.l    a0,IO_DATA(a1)
  471.     SYS    DoIO
  472.     tst.l    d0
  473.     bne    CleanUp
  474.     st    HandlerInstalled(a5)
  475.  
  476. ;Wait for signal(s)
  477. Wait:
  478.     tst.l    TaskQueue(a5)
  479.     bne    .DoTasks
  480.     lea    Sigs(a5),a0
  481.     move.l    (a0)+,d0
  482.     moveq    #NumSigs-2,d1
  483. ..    add.l    (a0)+,d0
  484.     dbra    d1,..
  485.     move.l    4,a6
  486.     SYS    Wait
  487.     move.l    d0,d7
  488.     move.l    d7,d1
  489.     and.l    QuitSig(a5),d1
  490.     bne    SafeCleanUp
  491.     move.l    d7,d1
  492.     and.l    FuncSig(a5),d1
  493.     beq    Wait
  494. .DoTasks:    move.l    IntBase(a5),a6
  495.     lea    TaskQueue(a5),a4
  496. .TaskLoop:
  497.     move.l    (a4),d0
  498.     beq    Wait
  499.     clr.l    (a4)+
  500.     move.l    d0,a0
  501.     bsr    GetSemaphore
  502.     jsr    (a0)
  503.     bsr    FreeSemaphore
  504.     bra    .TaskLoop
  505.  
  506. AmigaM:
  507.     move.l    ib_FirstScreen(a6),d0
  508.     beq    .End
  509.     move.l    d0,a0
  510.     jmp    _LVOScreenToBack(a6)
  511. .End:    rts
  512. AmigaN:    jmp    _LVOWBenchToFront(a6)
  513.  
  514. CTF:    bsr    GetWindow
  515.     tst.l    d0
  516.     beq    .NoCTF
  517.     move.l    CTFOption(a5),a2
  518.     move.l    (a2),d1
  519.     cmp.l    #1,d1
  520.     bhi    .MoreThanOne
  521.     bra    DoWindowToFront
  522. .MoreThanOne:
  523.     cmp.l    ClickWindow(a5),d0
  524.     beq    .SameWindow
  525.     move.l    d0,ClickWindow(a5)
  526.     moveq    #1,d0
  527.     move.l    d0,ClickCount(a5)
  528. .Time:    move.l    ib_Seconds(a6),ClickTime+TV_SECS(a5)
  529.     move.l    ib_Micros(a6),ClickTime+TV_MICRO(a5)
  530. .NoCTF:    rts
  531. .SameWindow:
  532.  
  533. ;Check to see whether MaxClickDelay has been exceeded. If not, increment
  534. ;ClickCount and compare with (CTFOption). If equal, do a WindowToFront.
  535. ;Window under pointer in D0.
  536.  
  537.     push    d0
  538.     move.l    ClickTime+TV_SECS(a5),d0
  539.     move.l    ClickTime+TV_MICRO(a5),d1
  540.     move.l    ib_Seconds(a6),d2
  541.     move.l    ib_Micros(a6),d3
  542.     SYS    DoubleClick
  543.     tst.l    d0
  544.     beq    .TimeExceeded
  545.     addq.l    #1,ClickCount(a5)
  546.     move.l    CTFOption(a5),a0
  547.     move.l    (a0),d0
  548.     cmp.l    ClickCount(a5),d0
  549.     bhi    .NeedMoreClicks
  550.     clr.l    ClickCount(a5)
  551.     pop    d0
  552.     bra    DoWindowToFront
  553. .TimeExceeded:
  554.     moveq    #1,d0
  555.     move.l    d0,ClickCount(a5)
  556. .NeedMoreClicks:
  557.     pop    d0
  558.     bra    .Time
  559.  
  560. CTB:    bsr    GetWindow
  561.     tst.l    d0
  562.     beq    .FlipScreen
  563.     move.l    d0,a1
  564.     move.l    wd_Flags(a1),d2
  565.     and.l    #WFLG_BACKDROP,d2
  566.     bne    .FlipScreen
  567.  
  568. ;Is this the only window on this screen, except for backdrop windows?
  569.     move.l    wd_WScreen(a1),a1
  570.     move.l    sc_FirstWindow(a1),a1
  571. .BackLoop:
  572.     cmp.l    a1,d0
  573.     beq    .EBackLoop
  574.     move.l    wd_Flags(a1),d2
  575.     and.l    #WFLG_BACKDROP,d2
  576.     beq    .FlipWindow
  577. .EBackLoop:
  578.     move.l    (a1),a1
  579.     move.l    a1,d2
  580.     bne    .BackLoop
  581. .FlipScreen:
  582.     tst.l    d1
  583.     beq    .End
  584.     move.l    d1,a0
  585.     jmp    _LVOScreenToBack(a6)
  586. .FlipWindow:
  587.     move.l    d0,a0
  588.     jmp    _LVOWindowToBack(a6)
  589. .End:    rts
  590.  
  591. PopCLI:
  592. ;Execute the desired command
  593.     move.l    a6,-(sp)
  594.     move.l    DosBase(a5),a6
  595.     move.l    CmdOption(a5),d1
  596.     beq    .End
  597.     lea    .Tags(pc),a0
  598.     move.l    a0,d2    ;tags
  599.     SYS    SystemTagList
  600.     tst.l    NoWBenchToFrontOption(a5)
  601.     bne    .SkipWBenchToFront
  602.     move.l    IntBase(a5),a6
  603.     SYS    WBenchToFront
  604. .SkipWBenchToFront:
  605. .End:    move.l    (sp)+,a6
  606.     rts
  607.  
  608. .Tags:    dc.l    SYS_UserShell,0
  609.     dc.l    NP_Priority,ShellPriority
  610.     dc.l    NP_StackSize
  611. CmdStackSize:
  612.     dc.l    0
  613.     dc.l    0    ;end of tag list
  614.  
  615. SafeCleanUp:
  616. ;Make sure the SetFunction'ed vectors are still intact.
  617.     lea    PatchTable(pc),a0
  618.     move.l    a0,a2
  619. .Safe:    move.w    (a0)+,d0
  620.     beq    CleanUp
  621.     move.l    (a5,d0.w),a1    ;library base
  622.     addq.l    #2,a0    ;skip version #
  623.     move.w    (a0)+,d0
  624.     lea    (a2,d0.w),a3    ;address of new routine
  625.     move.w    (a0)+,d0    ;_LVO offset
  626.     move.w    (a0)+,d1    ;Old vector
  627.     tst.l    (a5,d1.w)
  628.     beq    .Safe
  629.     cmp.l    2(a1,d0.w),a3
  630.     beq    .Safe
  631.  
  632. ;A routine has been patched by another program. Alert the user.
  633.  
  634.     move.l    IntBase(a5),a6
  635.     sub.l    a0,a0
  636.     lea    PatchAlert(pc),a1
  637.     sub.l    a2,a2
  638.     SYS    EasyRequestArgs
  639.     bra    Wait
  640. PatchAlert:
  641.     dc.l    es_SIZEOF
  642.     dc.l    0
  643.     dc.l    .TitleText-PatchAlert
  644.     dc.l    .AlertText-PatchAlert
  645.     dc.l    .OkayText-PatchAlert
  646. .TitleText:
  647.     dc.b    'QMouse message',0
  648. .AlertText:
  649.     dc.b    'Can''t quit or modify parameters. Another program '
  650.     dc.b    $a,'has patched the same OS routines!',0
  651. .OkayText:
  652.     dc.b    'OK',0
  653.     even
  654.  
  655. CleanUp:
  656.  
  657. ;Enter with global ptr in A5
  658.  
  659.     move.l    4,a6
  660.  
  661. ;Remove interrupt routine, if installed.
  662.     btst    #STB_IntInstalled,Status(a5)
  663.     beq    .SkipIntRemove
  664.     moveq    #INTB_VERTB,d0
  665.     lea    VBlankServer(a5),a1
  666.     SYS    RemIntServer
  667. .SkipIntRemove:
  668.  
  669. ;Remove input handler, if installed.
  670.     tst.b    HandlerInstalled(a5)
  671.     beq    .SkipHand
  672.     move.l    InputIORequest(a5),a1
  673.     move.w    #IND_REMHANDLER,IO_COMMAND(a1)
  674.     lea    InputInterrupt(a5),a0
  675.     move.l    a0,IO_DATA(a1)
  676.     SYS    DoIO
  677. .SkipHand:
  678.  
  679.     tst.l    OldCloseScreen(a5)
  680.     beq    .SkipRestore
  681.  
  682.     bsr    RestoreMouse
  683.     move.l    a5,a1    ;global
  684.     move.l    a5,a0    ;dummy ("input event")
  685.     bsr    RestoreScreen
  686.  
  687. ;Restore original vectors.
  688.  
  689.     lea    PatchTable(pc),a2
  690. .RestoreVecs:
  691.     move.w    (a2),d0
  692.     beq    .SkipRestore
  693.     addq.l    #6,a2    ;skip new routine info
  694.     move.l    (a5,d0.w),a1    ;get library base
  695.     move.w    (a2)+,a0    ;get _LVO
  696.     move.w    (a2)+,d0
  697.     move.l    (a5,d0.w),d0    ;old routine
  698.     beq    .RestoreVecs
  699.     SYS    SetFunction
  700.     bra    .RestoreVecs
  701. .SkipRestore:
  702.  
  703. ;Delay for 1/10 second to ensure that no-one is using the patch code.
  704.     move.l    DosBase(a5),d0
  705.     beq    .SkipFreeArg
  706.     move.l    d0,a6
  707.     moveq    #5,d1
  708.     SYS    Delay
  709.  
  710. ;Free argument structure
  711.     move.l    ArgPtr(a5),d1
  712.     beq    .SkipFreeArg
  713.     SYS    FreeArgs
  714. .SkipFreeArg:
  715.  
  716.     move.l    4,a6
  717.  
  718. ;Free signals
  719.     lea    Sigs(a5),a2
  720.     moveq    #NumSigs-1,d2
  721. .SigLoop:    move.l    (a2)+,d1
  722.     beq    .NextSig
  723.     moveq    #-1,d0
  724. .BitLoop:    addq.l    #1,d0
  725.     btst    d0,d1
  726.     beq    .BitLoop
  727.     SYS    FreeSignal
  728. .NextSig:    dbra    d2,.SigLoop
  729.  
  730. ;Remove flicker option, if selected.
  731.     tst.l    FlickerOption(a5)
  732.     beq    .SkipFlicker
  733.     move.l    OriginalCopInit(a5),a0
  734.     move.l    GraphBase(a5),a2
  735.     move.l    gb_copinit(a2),a1
  736. .CLoop:    move.l    (a1)+,(a0)+
  737.     cmp.l    #$008A0000,(a0)
  738.     bne    .CLoop
  739.     move.l    OriginalCopInit(a5),gb_copinit(a2)
  740.     move.l    OriginalCopInit(a5),cop1lc+_custom
  741. .SkipFlicker:
  742.  
  743. ;Close libraries
  744.     lea    LibTable+2(pc),a2
  745.     moveq    #NumLibs-1,d2
  746. .CLibLoop:
  747.     move.w    (a2),a0
  748.     add.l    a5,a0
  749.     tst.l    (a0)
  750.     beq    .SkipClose
  751.     move.l    (a0),a1
  752.     SYS    CloseLibrary
  753. .SkipClose:
  754.     addq.l    #4,a2
  755.     dbra    d2,.CLibLoop
  756.  
  757. ;Close input.device
  758.     move.l    InputIORequest(a5),d0
  759.     beq    .SkipCloseDev
  760.     move.l    d0,a1
  761.     tst.b    IO_ERROR(a1)    ;was there an error?
  762.     bne    .SkipCloseDev    ;yes, don't close
  763.     SYS    CloseDevice
  764. .SkipCloseDev:
  765.  
  766. ;Delete IORequest structure
  767.     move.l    InputIORequest(a5),a0
  768.     SYS    DeleteIORequest
  769.     move.l    InputMsgPort(a5),a0
  770.     SYS    DeleteMsgPort
  771.  
  772. ;Free chip data.
  773.     move.l    ChipData(a5),d0
  774.     beq    .SkipChipData
  775.     move.l    d0,a1
  776.     move.l    #CData_Sizeof,d0
  777.     SYS    FreeMem
  778. .SkipChipData:
  779.  
  780. ;Deallocate global structure. Note that this code is (sometimes) executed
  781. ;within the memory that we are freeing, so we are careful to terminate with
  782. ;a JMP.
  783.     move.l    a5,a1
  784.     move.l    #Data_Sizeof,d0
  785.     jmp    _LVOFreeMem(a6)
  786.  
  787. ;Semaphore routines
  788.  
  789. GetSemaphore:
  790.     rts
  791.     movem.l    a0/a6,-(sp)
  792.     move.l    GlobalPtr(pc),a0
  793.     lea    MySemaphore(a0),a0
  794.     move.l    4,a6
  795.     SYS    ObtainSemaphore
  796.     movem.l    (sp)+,a0/a6
  797.     rts
  798. FreeSemaphore:
  799.     rts
  800.     movem.l    a0/a6,-(sp)
  801.     move.l    GlobalPtr(pc),a0
  802.     lea    MySemaphore(a0),a0
  803.     move.l    4,a6
  804.     SYS    ReleaseSemaphore
  805.     movem.l    (sp)+,a0/a6
  806.     rts
  807.  
  808. Forbid:    move.l    a6,-(sp)
  809.     move.l    4,a6
  810.     SYS    Forbid
  811.     move.l    (sp)+,a6
  812.     rts
  813. Permit:    move.l    a6,-(sp)
  814.     move.l    4,a6
  815.     SYS    Permit
  816.     move.l    (sp)+,a6
  817.     rts
  818.  
  819.  
  820. LibTable:    dc.w    DosName-LibTable
  821.     dc.w    DosBase
  822.     dc.w    IntName-LibTable
  823.     dc.w    IntBase
  824.     dc.w    LayersName-LibTable
  825.     dc.w    LayersBase
  826.     dc.w    GraphName-LibTable
  827.     dc.w    GraphBase
  828.     dc.w    UtilityName-LibTable
  829.     dc.w    UtilityBase
  830. EndLibTable:
  831.  
  832. NumLibs    equ    (EndLibTable-LibTable)/4
  833.  
  834. ;****************** SetFunction'ed routines ***************
  835.  
  836. patch    macro
  837.     dc.w    \1
  838.     dc.w    \3    ;minimum library version
  839.     dc.w    New\2-PatchTable
  840.     dc.w    _LVO\2
  841.     dc.w    Old\2
  842.     endm
  843.  
  844. PatchTable:
  845.     patch    IntBase,SetWindowPointerA,39
  846.     patch    IntBase,OpenWindowTagList,39
  847.     patch    IntBase,CloseScreen,37
  848.     patch    IntBase,CloseWorkBench,37
  849.     patch    IntBase,CloseWindow,37
  850.     patch    IntBase,OpenScreen,37
  851.     patch    IntBase,ScreenToFront,37
  852.     patch    IntBase,ScreenToBack,37
  853.     patch    IntBase,OpenScreenTagList,37
  854.     patch    IntBase,WBenchToFront,37
  855.     patch    IntBase,WBenchToBack,37
  856.     patch    IntBase,SetPointer,37
  857.     patch    IntBase,ClearPointer,37
  858.     patch    IntBase,DisplayBeep,37
  859.     patch    GraphBase,LoadView,37
  860.     dc.w    0
  861.  
  862. NewDisplayBeep:
  863.     move.l    GlobalPtr(pc),a1
  864.     tst.l    BeepOption(a1)
  865.     bne    .SkipBeep
  866.     move.l    OldDisplayBeep(a1),-(sp)
  867. .SkipBeep:
  868.     rts
  869.  
  870. NewOpenWindowTagList:
  871. ;Enter with NewWindow in A0, taglist in A1
  872.     move.l    a1,-(sp)
  873.     pea    .HandlePointer(pc)
  874.     subq.l    #8,sp
  875.     move.l    a0,(sp)
  876.     move.l    GlobalPtr(pc),a0
  877.     move.l    OldOpenWindowTagList(a0),4(sp)
  878.     move.l    (sp)+,a0
  879. .End:    rts
  880. .RestoreD0:
  881.     move.l    (sp)+,d0
  882.     rts
  883. .HandlePointer:
  884.     move.l    (sp)+,a1
  885.     tst.l    d0
  886.     beq    .End
  887.     move.l    d0,a0
  888.     move.l    d0,-(sp)
  889.     pea    .RestoreD0(pc)
  890. ;    bra    NewSetWindowPointerA
  891.  
  892. NewSetWindowPointerA:
  893. ;Enter with:
  894. ;A0 - Window
  895. ;A1 - taglist
  896.  
  897. SaveRegs    setrl    d4-d5/a0-a6
  898.  
  899.     bsr    GetSemaphore
  900.     movem.l    SaveRegs,-(sp)
  901.     move.l    GlobalPtr(pc),a5
  902.     lea    PointerList(a5),a2
  903.  
  904. ;Find if window is already in table and find empty spot.
  905.     moveq    #POINTERLISTSIZE-1,d4
  906.     sub.l    a3,a3
  907. .WinSearch:
  908.     move.l    pt_Window(a2),d5
  909.     bne    .SkipSave
  910.     move.l    a2,a3
  911. .SkipSave:
  912.     cmp.l    d5,a0
  913.     beq    .Found
  914.     lea    pt_Sizeof(a2),a2
  915.     dbra    d4,.WinSearch
  916.     move.l    a3,a2
  917.     move.l    a2,d4
  918.     beq    .CallOld    ;no room in table, so forget it
  919. .Found:
  920. ;Store the taglist information
  921.     move.l    a0,a3    ;window
  922.     move.l    a1,a4    ;taglist
  923.     move.l    a0,pt_Window(a2)
  924.     st    TagVersion(a2)
  925.     move.l    UtilityBase(a5),a6
  926. ;Check for WA_BusyPointer.
  927.     move.l    #WA_BusyPointer,d0
  928.     move.l    a4,a0
  929.     SYS    FindTagItem
  930.     tst.l    d0
  931.     beq    .NotBusy
  932.     move.l    d0,a0
  933.  
  934.     IFNE    INFO_LEVEL
  935.     move.l    4(a0),-(sp)
  936.     move.l    (a0),-(sp)
  937.     PUTDEBUG    <'WA_BusyPointer=%lx,%lx '>
  938.     addq.l    #8,sp
  939.     ENDC
  940.  
  941.     move.l    (a0),(a2)
  942.     move.l    4(a0),4(a2)
  943.     beq    .NotBusy
  944.     clr.l    8(a2)
  945.     bra    .CallOld
  946. .NotBusy:
  947. ;Check for WA_Pointer.
  948.     move.l    #WA_Pointer,d0
  949.     move.l    a4,a0
  950.     SYS    FindTagItem
  951.     tst.l    d0
  952.     beq    .Nothing
  953.     move.l    d0,a0
  954.  
  955.     IFNE    INFO_LEVEL
  956.     move.l    4(a0),-(sp)
  957.     move.l    (a0),-(sp)
  958.     PUTDEBUG    <'WA_Pointer=%lx,%lx '>
  959.     addq.l    #8,sp
  960.     ENDC
  961.  
  962.     move.l    (a0),(a2)
  963.     move.l    4(a0),4(a2)
  964.     clr.l    8(a2)
  965.     bra    .CallOld
  966. .Nothing:
  967. ;Don't understand the taglist.
  968.     PUTDEBUG    <'Don''t grok SetWindowPointerA taglist!'>
  969.     clr.l    pt_Window(a2)
  970. .CallOld:    cmp.l    MBlankWindow(a5),a3
  971.     beq    .End
  972. ;Call old SetWindowPointerA
  973.     movem.l    (sp)+,SaveRegs
  974.     subq.l    #8,sp
  975.     move.l    a0,(sp)
  976.     move.l    GlobalPtr(pc),a0
  977.     move.l    OldSetWindowPointerA(a0),4(sp)
  978.     move.l    (sp)+,a0
  979.     bra    FreeSemaphore
  980. .End:    movem.l    (sp)+,SaveRegs
  981.     bra    FreeSemaphore
  982.  
  983. NewSetPointer:
  984.     bsr    GetSemaphore
  985.     movem.l    d4-d5/a2-a3/a5,-(sp)
  986.     move.l    GlobalPtr(pc),a5
  987.     cmp.l    ChipData(a5),a1    ;special check to ward off sneaky code like
  988.     beq    .End1        ;reqtools
  989.     lea    PointerList(a5),a2
  990.  
  991. ;Find if window is already in table and find empty spot.
  992.     moveq    #POINTERLISTSIZE-1,d4
  993.     sub.l    a3,a3
  994. .WinSearch:
  995.     move.l    pt_Window(a2),d5
  996.     bne    .SkipSave
  997.     move.l    a2,a3
  998. .SkipSave:
  999.     cmp.l    d5,a0
  1000.     beq    .Found
  1001.     lea    pt_Sizeof(a2),a2
  1002.     dbra    d4,.WinSearch
  1003.     move.l    a3,a2
  1004.     move.l    a2,d4
  1005.     beq    .End    ;no room in table, so forget it
  1006. .Found:    movem.l    d0-d3/a0-a1,(a2)
  1007.     clr.b    TagVersion(a2)
  1008. .End:    cmp.l    MBlankWindow(a5),a0
  1009.     beq    .End1
  1010.     movem.l    (sp)+,d4-d5/a2-a3/a5
  1011.     subq.l    #8,sp
  1012.     move.l    a0,(sp)
  1013.     move.l    GlobalPtr(pc),a0
  1014.     move.l    OldSetPointer(a0),4(sp)
  1015.     move.l    (sp)+,a0
  1016.     bra    FreeSemaphore
  1017. .End1:    movem.l    (sp)+,d4-d5/a2-a3/a5
  1018.     bra    FreeSemaphore
  1019.  
  1020. NewClearPointer:
  1021.     bsr    GetSemaphore
  1022.     move.l    GlobalPtr(pc),a1
  1023.     lea    PointerList(a1),a1
  1024.     moveq    #POINTERLISTSIZE-1,d0
  1025. .ClearLoop:
  1026.     cmp.l    pt_Window(a1),a0
  1027.     beq    .Found
  1028.     lea    pt_Sizeof(a1),a1
  1029.     dbra    d0,.ClearLoop
  1030.     bra    .End
  1031. .Found:    clr.l    pt_Window(a1)
  1032. .End:    move.l    GlobalPtr(pc),a1
  1033.     cmp.l    MBlankWindow(a1),a0
  1034.     beq    .End1
  1035.     move.l    OldClearPointer(a1),-(sp)
  1036. .End1:    bra    FreeSemaphore
  1037.  
  1038. NewLoadView:
  1039.     pea    .NewLoad(pc)
  1040.     move.l    GlobalPtr(pc),a0
  1041.     move.l    OldLoadView(a0),-(sp)
  1042.     rts
  1043. .NewLoad:
  1044.     move.l    GlobalPtr(pc),a0
  1045.     tst.l    FlickerOption(a0)
  1046.     beq    .End
  1047.     move.l    RealBackground(a0),a1
  1048.     move.l    GraphBase(a0),a0
  1049.     move.l    gb_copinit(a0),a0
  1050.     move.w    SysBackground(a0),(a1)
  1051. .End:    rts
  1052.  
  1053. NewCloseWorkBench:
  1054.     bsr    GetSemaphore
  1055.     SYS    OpenWorkBench    ;get workbench screen ptr in d0
  1056.     tst.l    d0
  1057.     beq    FreeSemaphore
  1058.     move.l    d0,a0
  1059.     move.l    GlobalPtr(pc),a1
  1060.     move.l    OldCloseWorkBench(a1),d1
  1061.     bset    #STB_InCloseWB,Status(a1)
  1062.     bra    CloseScreenCode
  1063.  
  1064. NewCloseScreen:
  1065.     bsr    GetSemaphore
  1066.     move.l    GlobalPtr(pc),a1
  1067.     move.l    OldCloseScreen(a1),d1
  1068.  
  1069. CloseScreenCode:
  1070. ;Code shared by NewCloseScreen and NewCloseWorkBench
  1071. ;Enter with Screen in A0, Global in A1, old vector in D1
  1072.  
  1073. ;Check for match in ScreenPtr
  1074.     cmp.l    ScreenPtr(a1),a0
  1075.     bne    .NotSP
  1076.     clr.l    ScreenPtr(a1)
  1077. .NotSP:
  1078.  
  1079.     lea    ScreenList(a1),a1
  1080.     moveq    #SCREENLISTSIZE-1,d0
  1081. .Loop:    cmp.l    (a1),a0
  1082.     beq    .Match
  1083.     addq.l    #8,a1
  1084.     dbra    d0,.Loop
  1085. .End:    move.l    GlobalPtr(pc),a1
  1086.     pea    .ExtraClose(pc)
  1087.     move.l    d1,-(sp)
  1088.     rts
  1089. .Match:    clr.l    (a1)
  1090.     bra    .End
  1091. .ExtraClose:
  1092.     move.l    GlobalPtr(pc),a0
  1093.     move.l    ib_FirstScreen(a6),CurrentTopScreen(a0)
  1094.     move.l    ib_ActiveScreen(a6),CurrentActiveScreen(a0)
  1095.     bclr    #STB_InCloseWB,Status(a0)
  1096.     bsr    FreeSemaphore
  1097.     bra    RestoreWindow
  1098.  
  1099. NewCloseWindow:
  1100.     move.l    GlobalPtr(pc),a1
  1101.     btst    #STB_InCloseWB,Status(a1)
  1102.     bne    .InWB
  1103.     bsr    GetSemaphore
  1104.     pea    .ExtraClose(pc)
  1105.     bra    .Cont
  1106. .InWB:    pea    .ExtraClose1(pc)
  1107. .Cont:    bsr    Forbid
  1108.     push    a0
  1109.     SYS    ClearPointer
  1110.     pop    a0
  1111.     move.l    GlobalPtr(pc),a1
  1112.     cmp.l    MBlankWindow(a1),a0
  1113.     bne    .SkipClear
  1114.     clr.l    MBlankWindow(a1)
  1115. .SkipClear:
  1116.     lea    ScreenList+4(a1),a1
  1117.     moveq    #SCREENLISTSIZE-1,d0
  1118. .Loop:    cmp.l    (a1),a0
  1119.     beq    .Match
  1120.     addq.l    #8,a1
  1121.     dbra    d0,.Loop
  1122. .End:    move.l    GlobalPtr(pc),a1
  1123.     bsr    Permit
  1124.     move.l    OldCloseWindow(a1),-(sp)
  1125.     rts
  1126. .Match:    clr.l    -4(a1)
  1127.     bra    .End
  1128. .ExtraClose:
  1129.     bsr    FreeSemaphore
  1130. .ExtraClose1:
  1131.     move.l    GlobalPtr(pc),a0
  1132.     bsr    Forbid
  1133.     move.l    ib_ActiveWindow(a6),CurrentActiveWindow(a0)
  1134.     move.l    ib_ActiveScreen(a6),CurrentActiveScreen(a0)
  1135.     bra    Permit
  1136.  
  1137. MyRemember:
  1138.     bsr    GetSemaphore
  1139.     movem.l    a0/a2/a4-a5,-(sp)
  1140.     move.l    GlobalPtr(pc),a5
  1141.     move.l    IntBase(a5),a4
  1142.     bsr    Forbid
  1143.     move.l    ib_ActiveScreen(a4),a0
  1144.     move.l    ib_ActiveWindow(a4),a2
  1145.     bsr    Permit
  1146.     bsr    RememberWindow
  1147.     move.l    (a5,d0.w),d0
  1148.     movem.l    (sp)+,a0/a2/a4-a5
  1149.     move.l    d0,-(sp)
  1150.     bra    FreeSemaphore
  1151.  
  1152. NewOpenScreen:
  1153.     move.w    #OldOpenScreen,d0
  1154.     bra    MyRemember
  1155. NewOpenScreenTagList:
  1156.     move.w    #OldOpenScreenTagList,d0
  1157.     bra    MyRemember
  1158. NewWBenchToFront:
  1159.     move.w    #OldWBenchToFront,d0
  1160. _MR:    bsr    MyRemember
  1161.     bra    RestoreWindow
  1162. NewWBenchToBack:
  1163.     move.w    #OldWBenchToBack,d0
  1164.     bra    _MR
  1165. NewScreenToFront:
  1166.     move.w    #OldScreenToFront,d0
  1167.     bra    _MR
  1168. NewScreenToBack:
  1169.     move.w    #OldScreenToBack,d0
  1170.     bra    _MR
  1171.  
  1172. ;****************** End of SetFunction'ed routines ***************
  1173.  
  1174. RememberWindow:
  1175.  
  1176. ;No OS calls
  1177. ;Enter with Screen in A0, Window in A2
  1178.  
  1179.     movem.l    d0-d1/a0-a2/a5,-(sp)
  1180.     move.l    GlobalPtr(pc),a5
  1181.  
  1182. ;Sanity checks
  1183.     move.l    a0,d0
  1184.     beq    .End
  1185.     move.l    a2,d0
  1186.     beq    .End
  1187.  
  1188.     lea    ScreenList(a5),a1
  1189.     moveq    #SCREENLISTSIZE-1,d0
  1190. .ScLoop:    cmp.l    (a1),a0
  1191.     beq    .Match
  1192.     addq.l    #8,a1
  1193.     dbra    d0,.ScLoop
  1194.  
  1195. ;Screen not found. Add to screen list.
  1196.     lea    ScreenList(a5),a1
  1197.     moveq    #SCREENLISTSIZE-1,d0
  1198. .AddLoop:    tst.l    (a1)
  1199.     beq    .Match
  1200.     addq.l    #8,a1
  1201.     dbra    d0,.AddLoop
  1202.     bra    .End    ;table is full
  1203. .Match:
  1204.     move.l    a0,(a1)+    ;screen
  1205.     move.l    a2,(a1)    ;currently activated window
  1206. .End:    movem.l    (sp)+,d0-d1/a0-a2/a5
  1207.     rts
  1208.  
  1209. RestoreWindow:
  1210.     movem.l    a1-a2,-(sp)
  1211.     move.l    GlobalPtr(pc),a1
  1212.     lea    TaskRestoreWindow(pc),a2
  1213.     bsr    DoFunc
  1214.     movem.l    (sp)+,a1-a2
  1215.     rts
  1216.  
  1217. TaskRestoreWindow:
  1218.  
  1219. ;This routine restores (re-activates) the previously activated window for
  1220. ;this screen.
  1221.  
  1222.     movem.l    d0-d2/a0-a2/a6,-(sp)
  1223.     move.l    GlobalPtr(pc),a0
  1224.     lea    ScreenList(a0),a2
  1225.     move.l    IntBase(a0),a6
  1226.     move.l    ib_FirstScreen(a6),d2
  1227.     beq    .End    ;sanity check
  1228.     move.l    d2,CurrentTopScreen(a0)
  1229.     tst.l    PubChangeOption(a0)
  1230.     beq    .NoPubChange
  1231.  
  1232. ;If the screen is public, make it the default public screen.
  1233.  
  1234.     SYS    LockPubScreenList
  1235. .PubLoop:    tst.l    d0
  1236.     beq    .EndPubChange
  1237.     move.l    d0,a0
  1238.     cmp.l    psn_Screen(a0),d2
  1239.     beq    .FoundScreen
  1240.     move.l    LN_SUCC(a0),d0
  1241.     bra    .PubLoop    
  1242. .FoundScreen:
  1243.     move.l    LN_NAME(a0),a0
  1244.     SYS    SetDefaultPubScreen
  1245.  
  1246. .EndPubChange:
  1247.     SYS    UnlockPubScreenList
  1248. .NoPubChange:
  1249.     move.l    d2,a0
  1250.     moveq    #SCREENLISTSIZE-1,d0
  1251. .Loop:    cmp.l    (a2),a0
  1252.     beq    .Match
  1253.     addq.l    #8,a2
  1254.     dbra    d0,.Loop
  1255.     move.l    sc_FirstWindow(a0),a0    ;default window
  1256.     move.l    a0,d0
  1257.     beq    .End    ;sanity check
  1258.     bra    .SkipMatch
  1259. .Match:
  1260.     move.l    4(a2),a0
  1261. .SkipMatch:
  1262.     SYS    ActivateWindow
  1263.     move.l    GlobalPtr(pc),a0
  1264.     move.l    ib_ActiveScreen(a6),CurrentActiveScreen(a0)
  1265. .End:    movem.l    (sp)+,d0-d2/a0-a2/a6
  1266.     rts
  1267.  
  1268.  
  1269. ;Get window associated with current mouse position.
  1270. ;Returns Window in D0 and screen in D1.
  1271.  
  1272. GetWindow:
  1273.     movem.l    d4/a0-a1/a4-a6,-(sp)
  1274.     move.l    GlobalPtr(pc),a5
  1275.     move.l    LayersBase(a5),a6
  1276.     move.l    IntBase(a5),a4
  1277.     move.l    ib_FirstScreen(a4),d4
  1278. .ScLoop:    tst.l    d4
  1279.     beq    .ErrEnd
  1280.     move.l    d4,a0
  1281.     move.l    sc_NextScreen(a0),d4
  1282.     move.w    sc_MouseX(a0),d0
  1283.     bmi    .ScLoop
  1284.     move.w    sc_MouseY(a0),d1
  1285.     bmi    .ScLoop
  1286.     push    a0
  1287.     lea    sc_LayerInfo(a0),a0
  1288.     SYS    WhichLayer
  1289.     pop    d1
  1290.     tst.l    d0
  1291.     beq    .End
  1292.     move.l    d0,a0
  1293.     move.l    lr_Window(a0),d0
  1294. .End:    movem.l    (sp)+,d4/a0-a1/a4-a6
  1295.     rts
  1296. .ErrEnd:    moveq    #0,d0
  1297.     moveq    #0,d1
  1298.     bra    .End
  1299.  
  1300. ActivateWindow:
  1301.  
  1302. ;Activate the window under the mouse pointer.
  1303. ;Enter with IntuitionBase in A6
  1304.  
  1305.     movem.l    d0-d1/a0-a1,-(sp)
  1306.     bsr    GetWindow
  1307.     tst.l    d0
  1308.     beq    .End
  1309.     move.l    d0,a0
  1310.     cmp.l    ib_ActiveWindow(a6),a0
  1311.     beq    .End
  1312.     tst.l    wd_FirstRequest(a0)
  1313.     bne    .End
  1314.     SYS    ActivateWindow
  1315. .End:    movem.l    (sp)+,d0-d1/a0-a1
  1316.     rts
  1317.  
  1318. DoWindowToFront:
  1319.  
  1320. ;Perform a WindowToFront on the window in D0.
  1321. ;Enter with IntuitionBase in A6.
  1322.  
  1323.     tst.l    d0
  1324.     beq    .End1
  1325.     movem.l    d0-d1/a0-a1/a6,-(sp)
  1326.     move.l    d0,a0
  1327.     move.l    wd_WLayer(a0),a1
  1328.     move.l    a1,d0
  1329.     beq    .End
  1330.     move.l    lr_ClipRect(a1),a1
  1331.     move.l    a1,d0
  1332.     beq    .End
  1333.     tst.l    (a1)
  1334.     beq    .End
  1335.     move.l    wd_Flags(a0),d0
  1336.     and.l    #WFLG_BACKDROP,d0
  1337.     bne    .End
  1338.     SYS    WindowToFront
  1339. .End:    movem.l    (sp)+,d0-d1/a0-a1/a6
  1340. .End1:    rts
  1341.  
  1342. BlankMouse:
  1343.     movem.l    d0-d3/a0-a1/a5-a6,-(sp)
  1344.     move.l    GlobalPtr(pc),a5
  1345.     move.l    IntBase(a5),a6
  1346.     move.l    ib_ActiveWindow(a6),d0
  1347.     beq    .End
  1348.     cmp.l    MBlankWindow(a5),d0
  1349.     beq    .End
  1350.     bsr    RestoreMouse
  1351.     move.l    d0,MBlankWindow(a5)
  1352.     move.l    d0,a0
  1353.     move.l    ChipData(a5),a1
  1354. ;    lea    ZeroMouse(a1),a1    ;not needed
  1355.     moveq    #1,d0    ;height
  1356.     moveq    #16,d1    ;width
  1357.     moveq    #0,d2    ;xoffset
  1358.     moveq    #0,d3    ;yoffset
  1359.     pea    .End(pc)
  1360.     move.l    OldSetPointer(a5),-(sp)
  1361.     rts
  1362. .End:    movem.l    (sp)+,d0-d3/a0-a1/a5-a6
  1363.     rts
  1364.  
  1365. RestoreMouse:
  1366.     movem.l    d0-d1/a0-a2/a5-a6,-(sp)
  1367.     move.l    GlobalPtr(pc),a5
  1368.     move.l    IntBase(a5),a6
  1369.     move.l    MBlankWindow(a5),d0
  1370.     beq    .End
  1371.  
  1372. ;Look for window in pointer table. If present, do a SetPointer or SetWindowPointerA
  1373. ;to restore the custom pointer. Otherwise call ClearPointer.
  1374.  
  1375.     move.l    d0,a0
  1376.     clr.l    MBlankWindow(a5)
  1377.     lea    PointerList(a5),a1
  1378.     moveq    #POINTERLISTSIZE-1,d0
  1379. .WinLoop:    cmp.l    pt_Window(a1),a0
  1380.     beq    .Found
  1381.     lea    pt_Sizeof(a1),a1
  1382.     dbra    d0,.WinLoop
  1383.     pea    .End(pc)
  1384.     move.l    OldClearPointer(a5),-(sp)
  1385.     rts
  1386. .End:    movem.l    (sp)+,d0-d1/a0-a2/a5-a6
  1387.     rts
  1388. .Found:    move.l    a1,a2
  1389.     tst.b    TagVersion(a2)
  1390.     beq    .NoTag
  1391. ;Call SetWindowPointerA to restore the custom pointer.
  1392.     move.l    pt_Window(a2),a0
  1393.     pea    .End(pc)
  1394.     move.l    OldSetWindowPointerA(a5),-(sp)
  1395.     rts
  1396. .NoTag:    movem.l    (a2),d0-d3/a0-a1
  1397.     pea    .End(pc)
  1398.     move.l    OldSetPointer(a5),-(sp)
  1399.     rts
  1400.  
  1401. ;***************************************************************************
  1402. ;Start of input handler code
  1403. ;***************************************************************************
  1404.  
  1405. BlankScreen:
  1406.  
  1407. ;Enter with global in A1.
  1408.     move.w    #DMAF_COPPER+DMAF_RASTER,dmacon+_custom
  1409.     clr.w    color+_custom
  1410.     bset    #STB_SBlanked,Status(a1)
  1411.     rts
  1412.  
  1413. RestoreScreen:
  1414.  
  1415. ;Enter with global in A1 AND input event in A0.
  1416.     move.l    ie_TimeStamp(a0),ScreenTime(a1)
  1417.     bclr    #STB_SBlanked,Status(a1)
  1418.     beq    .End
  1419.     move.w    #DMAF_SETCLR+DMAF_COPPER+DMAF_RASTER,dmacon+_custom
  1420. .End:    rts
  1421.  
  1422. DoFunc:
  1423.  
  1424. ;Enter with pointer to routine in A2
  1425. ;Enter with global ptr in A1.
  1426.  
  1427.     movem.l    d0-d1/a0-a1/a6,-(sp)
  1428.     lea    TaskQueue(a1),a0
  1429.     moveq    #MAXQUEUE-1,d0
  1430. ..    tst.l    (a0)+
  1431.     dbeq    d0,..
  1432.     bne    .End
  1433.     move.l    a2,-4(a0)
  1434.     move.l    FuncSig(a1),d0
  1435.     move.l    Task(a1),a1
  1436.     move.l    4,a6
  1437.     SYS    Signal
  1438. .End:    movem.l    (sp)+,d0-d1/a0-a1/a6
  1439.     rts
  1440.  
  1441. ;**************************** Input handler *********************************
  1442.  
  1443. IntRoutine:
  1444.     movem.l    d2/a2/a6,-(sp)
  1445.     move.l    a0,-(sp)
  1446.     bsr    Forbid
  1447.  
  1448.     move.l    IntBase(a1),a6
  1449. ;Handle NoFlicker option
  1450.     tst.l    FlickerOption(a1)
  1451.     beq    .SkipFlick
  1452.     move.l    GraphBase(a1),a0
  1453.     move.l    gb_LOFlist(a0),a2
  1454.     move.l    WaitLineAddress(a1),a0
  1455.     cmp.b    #WaitLine-1,WindowStart(a2)
  1456.     blo    .DisableNF
  1457.     move.b    #WaitLine,(a0)
  1458.     bra    .SkipDisableNF
  1459. .DisableNF:
  1460.     clr.b    (a0)
  1461. .SkipDisableNF:
  1462.     move.l    GraphBase(a1),a0
  1463.     move.l    gb_copinit(a0),a0
  1464.     cmp.w    #color,SysBackground-2(a0)
  1465.     bne    .DefColor
  1466.     move.w    SysBackground(a0),d0
  1467.     move.l    RealBackground(a1),a0
  1468.     move.w    d0,(a0)
  1469.     bra    .SkipColor
  1470. .DefColor:
  1471.     move.l    RealBackground(a1),a0
  1472.     move.w    #DefColor,(a0)
  1473. .SkipColor:
  1474.     move.l    (sp),a0
  1475. .SkipFlick:
  1476.  
  1477. ;Check for change in active screen.
  1478.     move.l    CurrentActiveScreen(a1),d0
  1479.     cmp.l    ib_ActiveScreen(a6),d0
  1480.     beq    .SameActiveScreen
  1481.     push    a0
  1482.     move.l    CurrentActiveScreen(a1),a0
  1483.     move.l    CurrentActiveWindow(a1),a2
  1484.     bsr    RememberWindow
  1485.     pop    a0
  1486. .SameActiveScreen:
  1487.  
  1488. ;Check for change in top screen.
  1489.     move.l    CurrentTopScreen(a1),d0
  1490.     beq    .CSZ
  1491.     cmp.l    ib_FirstScreen(a6),d0
  1492.     beq    .SkipRW
  1493.     push    a0
  1494.     move.l    CurrentActiveScreen(a1),a0
  1495.     move.l    CurrentActiveWindow(a1),a2
  1496.     bsr    RememberWindow
  1497.     pop    a0
  1498.     lea    TaskRestoreWindow(pc),a2
  1499.     bsr    DoFunc
  1500. .CSZ:    move.l    ib_FirstScreen(a6),CurrentTopScreen(a1)
  1501. .SkipRW:    move.l    ib_ActiveWindow(a6),CurrentActiveWindow(a1)
  1502.     move.l    ib_ActiveScreen(a6),CurrentActiveScreen(a1)
  1503.  
  1504. ;Re-blank mouse if a new window has been activated.
  1505.     move.l    MBlankWindow(a1),d0
  1506.     beq    .Loop
  1507.     cmp.l    ib_ActiveWindow(a6),d0
  1508.     beq    .EndMBW
  1509.     lea    BlankMouse(pc),a2
  1510.     bsr    DoFunc
  1511. .EndMBW:
  1512.  
  1513. .Loop:    cmp.b    #IECLASS_TIMER,ie_Class(a0)
  1514.     beq    .Timer
  1515.  
  1516.     cmp.b    #IECLASS_RAWKEY,ie_Class(a0)
  1517.     bne    .NotKey
  1518.     tst.b    ie_Code+1(a0)
  1519.     bmi    .Next    ;ignore up key codes
  1520.  
  1521.     bsr    RestoreScreen
  1522.  
  1523. ;Handle immediate blank feature
  1524.     tst.l    ImmBlankOption(a1)
  1525.     beq    .SkipImmBlank
  1526. ;Check for lamiga+ramiga
  1527.     cmp.b    #IEQUALIFIER_LCOMMAND+IEQUALIFIER_RCOMMAND,ie_Qualifier+1(a0)
  1528.     bne    .SkipImmBlank
  1529.     bsr    BlankScreen
  1530. .SkipImmBlank:
  1531.  
  1532. ;Perform SunKey
  1533.     tst.l    SunKeyOption(a1)
  1534.     beq    .SkipSKey
  1535.     lea    ActivateWindow(pc),a2
  1536.     bsr    DoFunc
  1537. .SkipSKey:
  1538.  
  1539. ;Do Northgate keyboard mapping.
  1540.     tst.l    NorthGateOption(a1)
  1541.     beq    .SkipNorthgate
  1542.     lea    NorthgateTable(pc),a2
  1543.     move.w    ie_Code(a0),d0
  1544.     bclr    #7,d0
  1545. .NorthgateLoop:
  1546.     move.b    (a2),d1
  1547.     beq    .EndNorthgate
  1548.     addq.l    #3,a2
  1549.     cmp.b    d0,d1
  1550.     bne    .NorthgateLoop
  1551.     and.w    #$80,ie_Code(a0)
  1552.     move.b    -2(a2),d0
  1553.     or.b    d0,ie_Code+1(a0)
  1554.     move.b    -1(a2),d0
  1555.     bmi    .EndNorthgate
  1556.     bset    d0,ie_Qualifier+1(a0)
  1557. .EndNorthgate:
  1558. .SkipNorthgate:
  1559.  
  1560.     btst    #IEQUALIFIERB_LCOMMAND,ie_Qualifier+1(a0)
  1561.     bne    .DoLAmiga
  1562.  
  1563. ;Blank mouse pointer
  1564.     tst.l    MBlankOption(a1)
  1565.     beq    .NoMBlank
  1566.     lea    BlankMouse(pc),a2
  1567.     bsr    DoFunc
  1568. .NoMBlank:
  1569.     bra    .Next
  1570.  
  1571. .DoLAmiga:
  1572.     cmp.w    #$37,ie_Code(a0)    ;'m'?
  1573.     bne    .NotM
  1574.  
  1575. ;We found an Amiga-M. Defuse and perform action.
  1576.     clr.b    ie_Class(a0)
  1577.     lea    AmigaM(pc),a2
  1578.     bsr    DoFunc
  1579.     bra    .End
  1580.  
  1581. .NotM:    cmp.w    #$36,ie_Code(a0)    ;'n'?
  1582.     bne    .NotN
  1583.  
  1584. ;We found an Amiga-N. Defuse and perform action.
  1585.     clr.b    ie_Class(a0)
  1586.     lea    AmigaN(pc),a2
  1587.     bsr    DoFunc
  1588.     bra    .End
  1589.  
  1590. .NotN:    tst.l    CmdOption(a1)
  1591.     beq    .Next
  1592.     cmp.w    #$45,ie_Code(a0)    ;ESC?
  1593.     bne    .Next
  1594.     clr.b    ie_Class(a0)
  1595.     lea    PopCLI(pc),a2
  1596.     bsr    DoFunc
  1597.     bra    .End
  1598.  
  1599. .NotKey:    bsr    RestoreScreen
  1600. .Timer:    move.w    ib_MouseX(a6),d0
  1601.     move.w    ib_MouseY(a6),d1
  1602.     cmp.b    #IECLASS_RAWMOUSE,ie_Class(a0)
  1603.     beq    .DoMouse
  1604.     cmp.w    CurrentX(a1),d0
  1605.     bne    .DoMouse
  1606.     cmp.w    CurrentY(a1),d1
  1607.     beq    .Next
  1608.  
  1609. .DoMouse:
  1610.     move.w    d0,CurrentX(a1)
  1611.     move.w    d1,CurrentY(a1)
  1612.     tst.l    MBlankOption(a1)
  1613.     beq    .NoRestore
  1614.     move.l    ie_TimeStamp(a0),MouseTime(a1)
  1615.     lea    RestoreMouse(pc),a2
  1616.     bsr    DoFunc
  1617. .NoRestore:
  1618.  
  1619. ;Perform SunMouse
  1620.     tst.l    SunMouseOption(a1)
  1621.     beq    .SkipSunMouse
  1622.     move.w    ie_Qualifier(a0),d0
  1623.     and.w    #IEQUALIFIER_LEFTBUTTON+IEQUALIFIER_RBUTTON+IEQUALIFIER_MIDBUTTON,d0
  1624.     bne    .SkipSunMouse
  1625.     cmp.w    #IECODE_LBUTTON+IECODE_UP_PREFIX,ie_Code(a0)
  1626.     beq    .SkipSunMouse
  1627.     move.l    SunMouseDelayOption(a1),a2
  1628.     move.l    a2,d0
  1629.     beq    .SkipLoad
  1630.     move.l    (a2),d0
  1631. .SkipLoad:
  1632.     addq.l    #1,d0
  1633.     move.l    d0,SunMouseDelay(a1)
  1634. .SkipSunMouse:
  1635.  
  1636. ;Perform click-to-back.
  1637.     cmp.w    #IECODE_RBUTTON,ie_Code(a0)
  1638.     bne    .NoCTB
  1639.     move.w    ie_Qualifier(a0),d0
  1640.     btst    #IEQUALIFIERB_LEFTBUTTON,d0
  1641.     beq    .DoSunRMB
  1642.     tst.l    CTBOption(a1)
  1643.     beq    .NoCTB
  1644.     lea    CTB(pc),a2
  1645.     bsr    DoFunc
  1646.     clr.b    ie_Class(a0)
  1647.     bra    .Next
  1648.  
  1649. .DoSunRMB:
  1650.  
  1651. ;Perform SunRMB
  1652.     tst.l    SunRMBOption(a1)
  1653.     beq    .SkipSunRMB
  1654.     lea    ActivateWindow(pc),a2
  1655.     bsr    DoFunc
  1656. .SkipSunRMB:
  1657.  
  1658. .NoCTB:
  1659.  
  1660. ;Perform click-to-front.
  1661.     tst.l    CTFOption(a1)
  1662.     beq    .NoCTF
  1663.     cmp.w    #IECODE_LBUTTON,ie_Code(a0)
  1664.     bne    .NoCTF
  1665.     btst    #IEQUALIFIERB_LCOMMAND,ie_Qualifier+1(a0)
  1666.     bne    .NoCTF    ;to avoid interferring with Snap
  1667.     lea    CTF(pc),a2
  1668.     bsr    DoFunc
  1669. .NoCTF:
  1670.  
  1671. ;Perform acceleration.
  1672.     tst.l    AccelOption(a1)
  1673.     beq    .Next
  1674.  
  1675.     move.l    ThreshOption(a1),d0
  1676.     beq    .T1
  1677.     move.l    d0,a2
  1678.     move.l    (a2),d0
  1679. .T1:    move.w    ie_X(a0),d1
  1680.     bpl    .PosX
  1681.     neg.w    d1
  1682. .PosX:    cmp.w    d0,d1
  1683.     bls    .SkipX    ;below threshold
  1684.     move.l    AccelOption(a1),a2
  1685.     move.l    (a2),d1
  1686.     muls.w    ie_X(a0),d1
  1687.     tst.w    ie_X(a0)
  1688.     bpl    .SubDampX
  1689.     add.w    DampingConstant(a1),d1
  1690.     bra    .DampX
  1691. .SubDampX:
  1692.     sub.w    DampingConstant(a1),d1
  1693. .DampX:    move.w    d1,ie_X(a0)
  1694. .SkipX:    move.w    ie_Y(a0),d1
  1695.     bpl    .PosY
  1696.     neg.w    d1
  1697. .PosY:    cmp.w    d0,d1
  1698.     bls    .EndAccel
  1699.     move.l    AccelOption(a1),a2
  1700.     move.l    (a2),d1
  1701.     muls.w    ie_Y(a0),d1
  1702.     tst.w    ie_Y(a0)
  1703.     bpl    .SubDampY
  1704.     add.w    DampingConstant(a1),d1
  1705.     bra    .DampY
  1706. .SubDampY:
  1707.     sub.w    DampingConstant(a1),d1
  1708.  
  1709. .DampY:    move.w    d1,ie_Y(a0)
  1710. .EndAccel:
  1711.  
  1712. .Next:    move.l    a0,d1
  1713.     move.l    (a0),d0
  1714.     move.l    d0,a0
  1715.     bne    .Loop
  1716.  
  1717. ;Check for time-outs (mouse and screen blanking)
  1718.     move.l    d1,a0
  1719.     tst.l    MBlankOption(a1)
  1720.     beq    .NoMTime
  1721.     tst.l    MBlankWindow(a1)
  1722.     bne    .NoMTime
  1723.     move.l    MBlankOption(a1),a0
  1724.     move.l    (a0),d0    ;get value in seconds
  1725.     move.l    d1,a0
  1726.     move.l    ie_TimeStamp(a0),d1
  1727.     tst.l    MouseTime(a1)
  1728.     beq    .InitMBlank
  1729.     sub.l    MouseTime(a1),d1
  1730.     cmp.l    d0,d1    ;TimePassed ? UserSetting
  1731.     blo    .NoMTime
  1732.     lea    BlankMouse(pc),a2
  1733.     bsr    DoFunc
  1734. .NoMTime:
  1735.     tst.l    SBlankOption(a1)
  1736.     beq    .End
  1737.     btst    #STB_SBlanked,Status(a1)
  1738.     bne    .End
  1739.     push    a0
  1740.     move.l    SBlankOption(a1),a0
  1741.     move.l    (a0),d0    ;get value in seconds
  1742.     pop    a0
  1743.     move.l    ie_TimeStamp(a0),d1
  1744.     tst.l    ScreenTime(a1)
  1745.     beq    .InitSBlank
  1746.     sub.l    ScreenTime(a1),d1
  1747.     cmp.l    d0,d1    ;TimePassed ? UserSetting
  1748.     blo    .End
  1749.     bsr    BlankScreen
  1750.  
  1751. .End:    move.l    (sp)+,d0
  1752.     bsr    Permit
  1753. .EndEnd:    movem.l    (sp)+,d2/a2/a6
  1754.     rts
  1755. .InitMBlank:
  1756.     move.l    ie_TimeStamp(a0),MouseTime(a1)
  1757.     bra    .NoMTime
  1758. .InitSBlank:
  1759.     move.l    ie_TimeStamp(a0),ScreenTime(a1)
  1760.     bra    .End
  1761.  
  1762. ;Enter with global pointer in A1.
  1763. ;d0, d1, a0, a1, a5, and a6 are scratch.
  1764. ;Must always end with a "moveq #0,d0" to set the Z flag.
  1765.  
  1766. VBlankRoutine:
  1767.     tst.l    SunMouseDelay(a1)
  1768.     beq    .End
  1769.     subq.l    #1,SunMouseDelay(a1)
  1770.     bne    .End
  1771.     move.l    a2,-(sp)
  1772.     lea    ActivateWindow(pc),a2
  1773.     bsr    DoFunc
  1774.     move.l    (sp)+,a2
  1775. .End:    moveq    #0,d0
  1776.     rts
  1777.  
  1778. GlobalPtr:
  1779.     dc.l    0
  1780.  
  1781. NorthgateTable:
  1782. ;Assign PageUp/PageDown/Home/End to shift-cursor sequences
  1783.     dc.b    $6b,$4f,IEQUALIFIERB_LSHIFT
  1784.     dc.b    $6c,$4e,IEQUALIFIERB_LSHIFT
  1785.     dc.b    $6d,$4c,IEQUALIFIERB_LSHIFT
  1786.     dc.b    $6e,$4d,IEQUALIFIERB_LSHIFT
  1787.  
  1788. ;Change a couple keypad key assignments to be more Amiga-like.
  1789.     dc.b    $5c,$5b,0    ;'/' key -> ')' key
  1790.     dc.b    $5d,$5c,0    ;'*' key -> '/' key
  1791.     dc.b    $4a,$5d,0    ;'-' key -> '*' key
  1792.     dc.b    0
  1793.  
  1794. ProcName:    dc.b    'QMouse process',0
  1795. InputName:
  1796.     dc.b    'input.device',0
  1797. TrackName:
  1798.     dc.b    'trackdisk.device',0
  1799.     even
  1800.  
  1801. ;*************************** Debugging stuff *************************
  1802.  
  1803.     IFNE    INFO_LEVEL
  1804. KPutFmt:    movem.l    a2/a6,-(sp)
  1805.     move.l    4,a6
  1806.     lea    KPutChar(pc),a2
  1807.     SYS    RawDoFmt
  1808.     movem.l    (sp)+,a2/a6
  1809.     rts
  1810.  
  1811. KPutChar:
  1812.  
  1813. ;Serial
  1814.     comment |
  1815.     move.l    a6,-(sp)
  1816.     move.l    4,a6
  1817.     SYS    RawPutChar
  1818.     move.l    (sp)+,a6
  1819.     rts
  1820. |
  1821.  
  1822. ;Printer
  1823.     comment |
  1824.     move.b    #$ff,$bfe301
  1825. .Print:    btst    #0,$bfd000
  1826.     bne    .Print
  1827.     move.b    d0,$bfe101
  1828.     rts
  1829. |
  1830.  
  1831. ;Memory
  1832.     movem.l    a0-a1,-(sp)
  1833.     lea    MemPtr(pc),a1
  1834.     move.l    (a1),a0
  1835.     move.b    d0,(a0)+
  1836.     move.l    a0,(a1)
  1837.     movem.l    (sp)+,a0-a1
  1838.     rts
  1839. MemPtr:    dc.l    $300000
  1840.     ENDC
  1841.  
  1842. EndAllocCode:    ;end of code copied into allocated memory
  1843. ;***********************************************************************
  1844.  
  1845. NewProcTags:
  1846.     dc.l    NP_Entry
  1847. EntryPoint:
  1848.     dc.l    0
  1849.     dc.l    NP_Name
  1850. ProcNamePtr:
  1851.     dc.l    0
  1852.     dc.l    NP_Cli,-1
  1853.     dc.l    NP_Priority,TaskPriority
  1854.     dc.l    0    ;end of tags
  1855.  
  1856. Template:    dc.b    'M=MBLANK/K/N,'
  1857.     dc.b    'S=SBLANK/K/N,'
  1858.     dc.b    'N=NOFLICKER/S,'
  1859.     dc.b    'CMD/K,'
  1860.     dc.b    'A=ACCELERATION/K/N,'
  1861.     dc.b    'T=THRESHOLD/K/N,'
  1862.     dc.b    'CTB=CLICKTOBACK/S,'
  1863.     dc.b    'CTF=CLICKTOFRONT/K/N,'
  1864.     dc.b    'SUNMOUSE/S,'
  1865.     dc.b    'SUNKEY/S,'
  1866.     dc.b    'SunRMB/S,'
  1867.     dc.b    'NORTHGATE/S,'
  1868.     dc.b    'NOBEEP/S,'
  1869.     dc.b    'NOCLICK/K/N,'
  1870.     dc.b    'VERIFY/S,'
  1871.     dc.b    'NOVERIFY/S,'
  1872.     dc.b    'STAR/S,'
  1873.     dc.b    'NoWBenchToFront/S,'
  1874.     dc.b    'PUBCHANGE/S,'
  1875.     dc.b    'SunMouseDelay/K/N,'
  1876.     dc.b    'ImmBlank/S,'
  1877.     dc.b    'QUIT/S',0
  1878.  
  1879. IntName:    dc.b    'intuition.library',0
  1880. GraphName:
  1881.     dc.b    'graphics.library',0
  1882. DosName:    dc.b    'dos.library',0
  1883. LayersName:
  1884.     dc.b    'layers.library',0
  1885. UtilityName:
  1886.     dc.b    'utility.library',0
  1887.  
  1888. ;The ordering here is special: data registers first, then address
  1889. ;registers, so that MOVEM may be used to save/restore the data.
  1890.  
  1891.     STRUCTURE    pt,0
  1892.     LONG    pt_Height
  1893.     LONG    pt_Width
  1894.     LONG    pt_XOffset
  1895.     LONG    pt_YOffset
  1896.     LONG    pt_Window
  1897.     LONG    pt_Pointer
  1898.     BYTE    TagVersion    ;special boolean indicator
  1899.     BYTE    pt_pad
  1900.     LABEL    pt_Sizeof
  1901.  
  1902. ResidentCodeSize    equ    EndAllocCode-StartAllocCode
  1903.  
  1904.     STRUCTURE    Data,0
  1905.     WORD    Nothing    ;to make zero special
  1906.  
  1907.     LABEL    Sigs
  1908.     LONG    QuitSig
  1909.     LONG    FuncSig
  1910.     LABEL    EndSigs
  1911.  
  1912.     LABEL    Semaphores
  1913.     STRUCT    MySemaphore,SS_SIZE
  1914.     LABEL    EndSemaphores
  1915.  
  1916.     LONG    Task
  1917.     LONG    InputMsgPort
  1918.     LONG    InputIORequest
  1919.     STRUCT    InputInterrupt,IS_SIZE
  1920.     LONG    IntBase
  1921.     LONG    GraphBase
  1922.     LONG    LayersBase
  1923.     LONG    UtilityBase
  1924.     STRUCT    ScreenList,SCREENLISTSIZE*8
  1925.     STRUCT    PointerList,POINTERLISTSIZE*pt_Sizeof
  1926.     STRUCT    TaskQueue,MAXQUEUE*4+4
  1927.     LONG    OldCloseScreen
  1928.     LONG    OldCloseWorkBench
  1929.     LONG    OldCloseWindow
  1930.     LONG    OldScreenToFront
  1931.     LONG    OldScreenToBack
  1932.     LONG    OldOpenScreen
  1933.     LONG    OldOpenScreenTagList
  1934.     LONG    OldWBenchToFront
  1935.     LONG    OldWBenchToBack
  1936.     LONG    OldLoadView
  1937.     LONG    OldSetPointer
  1938.     LONG    OldSetWindowPointerA
  1939.     LONG    OldClearPointer
  1940.     LONG    OldDisplayBeep
  1941.     LONG    OldOpenWindowTagList
  1942.     LONG    DosBase
  1943.     LONG    ArgPtr
  1944.     STRUCT    ResidentCode,ResidentCodeSize
  1945.     LONG    MouseTime    ;timeout for mouse blanking
  1946.     LONG    ScreenTime    ;for screen blanking
  1947.     LONG    MBlankWindow
  1948.     WORD    DampingConstant
  1949.     LONG    ClickWindow
  1950.     STRUCT    ClickTime,TV_SIZE
  1951.     LONG    ClickCount
  1952.     LONG    Path
  1953.     LONG    ChipData
  1954.     LONG    RealBackground
  1955.     LONG    OriginalCopInit
  1956.     LONG    ScreenPtr
  1957.     WORD    CurrentX
  1958.     WORD    CurrentY
  1959.     LONG    WaitLineAddress
  1960.     LONG    CurrentTopScreen
  1961.     LONG    CurrentActiveScreen
  1962.     LONG    CurrentActiveWindow
  1963.     LONG    SunMouseDelay
  1964.     STRUCT    VBlankServer,IS_SIZE
  1965.  
  1966.     LABEL    Options
  1967.     LONG    MBlankOption
  1968.     LONG    SBlankOption
  1969.     LONG    FlickerOption
  1970.     LONG    CmdOption
  1971.     LONG    AccelOption
  1972.     LONG    ThreshOption
  1973.     LONG    CTBOption
  1974.     LONG    CTFOption
  1975.     LONG    SunMouseOption
  1976.     LONG    SunKeyOption
  1977.     LONG    SunRMBOption
  1978.     LONG    NorthGateOption
  1979.     LONG    BeepOption
  1980.     LONG    NoClickOption
  1981.     LONG    VerifyOption
  1982.     LONG    NoVerifyOption
  1983.     LONG    StarOption
  1984.     LONG    NoWBenchToFrontOption
  1985.     LONG    PubChangeOption
  1986.     LONG    SunMouseDelayOption
  1987.     LONG    ImmBlankOption
  1988.     LONG    QuitOption
  1989.  
  1990.     BYTE    HandlerInstalled
  1991.     BYTE    Status    ;various status bits (defined below)
  1992.     LABEL    Data_Sizeof
  1993.  
  1994. ;Bit definitions for Status
  1995.     BITDEF    ST,SBlanked,0
  1996.     BITDEF    ST,IntInstalled,1
  1997.     BITDEF    ST,InCloseWB,2
  1998.  
  1999. NumSigs    equ    (EndSigs-Sigs)/4
  2000. NumSemaphores    equ    (EndSemaphores-Semaphores)/SS_SIZE
  2001.  
  2002.     STRUCTURE    CData,0
  2003.     STRUCT    ZeroMouse,12
  2004.     STRUCT    Copper,MaxCopperSize+4*4
  2005.     LABEL    CData_Sizeof
  2006.  
  2007.     end
  2008.